package cn.bonoon.controllers.account;

import static org.springframework.web.bind.annotation.RequestMethod.GET;
import static org.springframework.web.bind.annotation.RequestMethod.POST;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import cn.bonoon.core.plugins.AccountService;
import cn.bonoon.core.plugins.RoleService;
import cn.bonoon.entities.plugins.AccountEntity;
import cn.bonoon.entities.plugins.RoleEntity;
import cn.bonoon.kernel.menus.ChannelInfo;
import cn.bonoon.kernel.menus.IModuleInfo;
import cn.bonoon.kernel.menus.MenuInfo;
import cn.bonoon.kernel.menus.ModuleManager;
import cn.bonoon.kernel.menus.TabInfo;
import cn.bonoon.kernel.menus.TabItem;
import cn.bonoon.kernel.support.models.Node;
import cn.bonoon.kernel.util.StringHelper;
import cn.bonoon.kernel.web.controllers.AbstractController;
import cn.bonoon.kernel.web.models.DialogModel;
import cn.bonoon.kernel.web.models.JsonResult;

@Controller
@RequestMapping("s/sys/account")
public class AccountAssignRoleController extends AbstractController {

	@Autowired
	private RoleService roleService;
	@Autowired
	private AccountService accountService;
	@Autowired
	private ModuleManager moduleManager;
	
	@RequestMapping(value = "!{mid}/assign.do", method = { POST, GET })
	public ModelAndView get(HttpServletRequest request, @PathVariable("mid") String mid, Long id, String gridid) {
		DialogModel model = new DialogModel(mid, request);
		model.addForm(id);
		model.addObject("gridid", gridid);
		model.addObject("id", id);
		AccountEntity account = accountService.get(id);
		model.addObject("name", account.getName());
		model.addObject("loginName", account.getLoginName());
		// 超级管理员可以分配所有的角色，一般的管理员只允许分配由他创建的那些角色
//		List<RoleEntity> roles = roleService.getRoles(getUser());
		List<Long> user_roles = roleService.getRolesId(id);
		StringBuffer html = new StringBuffer();
		for (RoleEntity role : roleService.getRoles(getUser())) {
			Long rid = role.getId();
			html.append("<input type='checkbox' id='role_chk_").append(rid).append("' ");
			if (user_roles.contains(rid)) {
				html.append("checked='true'");
			}
			html.append(" />&nbsp;<a href='#' id='role_a_").append(rid).append("'>").append(role.getName()).append("</a><br/>");
		}
		model.addObject("roles", html);
		return model.execute("sys/account/account-assign");
	}
	
//	private List<String> selectedIds; // 角色已有的菜单权限
	
	@ResponseBody
	@RequestMapping(value = "!{mid}/assign/!{rid}/privileges", method = { POST, GET })
	public List<Node> privileges(HttpServletRequest request, @PathVariable("mid") String mid, @PathVariable("rid") Long rid) {
		if (null == rid) return null;
		RoleEntity role = roleService.get(rid);
		if (null == role) return null;
		
		IModuleInfo mi = moduleManager.module(role.getModuleKey()); 		// 获取子系统信息
		List<String> selectedIds = roleService.getPrivilegeMeunId(rid); 				// 角色已有的菜单权限
		List<Node> module_nodes = new ArrayList<Node>(); 				// 子系统节点（根节点）
		Node module_node = new Node(mi.getId(), mi.getName());
		
		List<Node> nodes = new ArrayList<Node>(); 						// 频道节点
//		List<Node> menus;												// 菜单节点
//		Node node;
//		List<TabInfo> tabs;
		for (ChannelInfo ci : mi.getChannels()) { 						// 循环该子系统下的所有频度
			Node node = new Node(ci.getId(), ci.getName(), mi.getId());
			List<Node> menus = visitMenus(ci.getMenus(), ci.getId(), selectedIds); 	// 递归该频度下所有菜单
			// tab
//			tabs = ci.getTabs();
//			if (null != tabs) {
			List<Node> tab_nodes = new ArrayList<Node>();
//				Node tab_node, tabitem_node;
			for (TabInfo ti : ci.getTabs()) {
				String tid = ti.getId();
				Node tab_node = new Node(tid, ti.getName(), ci.getId());
				boolean tab_checked = selectedIds.contains(tid);
				if(tab_checked){
					tab_node.setChecked(true);
					tab_node.setIconCls("icon-accept");
				}
				List<Node> tabitem_nodes = new ArrayList<Node>();
				for (TabItem item : ti.getItems()) {
					Node tabitem_node = new Node(item.getId(), item.getName(), tid);
					if(selectedIds.contains(item.getId())){
						tabitem_node.setChecked(true);
						tabitem_node.setIconCls("icon-accept");
					}
					tabitem_nodes.add(tabitem_node);
				}
				if (!tabitem_nodes.isEmpty()) {
					tab_node.setChildren(tabitem_nodes);
				}
				if (getUser().isSuper() || tab_checked) {
					tab_nodes.add(tab_node);
				}
			}
			if (!tab_nodes.isEmpty()) {
				menus.addAll(tab_nodes); // 把 tabs 加在 menus 的下面，父节点是频道
			}
//			}
			// ~tab

			if (null != menus && !menus.isEmpty()) {
				node.setChildren(menus);
			}
			if (getUser().isSuper() || (null != node.getChildren() && !node.getChildren().isEmpty())) {
				nodes.add(node);
			}

		}
		module_node.setChildren(nodes);
		module_nodes.add(module_node);
		return module_nodes;
	}
	
	private List<Node> visitMenus(List<MenuInfo> menus, String parentId, List<String> selectedIds) {
		if (null == menus || menus.isEmpty())
			return null;
		
		List<Node> nodes = new ArrayList<Node>(); // 菜单节点
		for (MenuInfo mi : menus) {
			String mid = mi.getId();
			Node _node = new Node(mid, mi.getName(), parentId);
			if(selectedIds.contains(mid)){
				_node.setChecked(true);
				_node.setIconCls("icon-accept");
				nodes.add(_node);
			}else if(getUser().isSuper()) {
				nodes.add(_node);
			}else{
				continue;
			}
			// 子菜单节点
			List<Node> children = visitMenus(mi.getMenus(), mid, selectedIds); // 递归子菜单
			if (null != children && !children.isEmpty()) {
				_node.setChildren(children);
			}
		}
		return nodes;
	}

	@ResponseBody
	@RequestMapping(value = "!{mid}/assign!save.b", method = POST)
	public final JsonResult assign(HttpServletRequest request, @PathVariable("mid") String mid, final Long id, String roles) {
		Long[] roleIds = StringHelper.toLongArray(roles, ",");
		roleService.saveAssignRole(getUser(), id, roleIds);
		return JsonResult.result();
	}

}
